#define copy(a,b,st) (memcpy(a,b,sizeof(st)))
inline cli(void);
inline sti(void);
void delay(unsigned long del);
unsigned char bcd2binary(unsigned char al);
typedef unsigned size_t;
size_t strlen(const char *str);
int strcmp(const char *string1,const char *string2);
void *memcpy(void *dst_ptr, const void *src_ptr, size_t count);
void *memsetw(void *dst, int val, size_t count);
void clearmem(unsigned char *buffer,unsigned long count);
unsigned long pow(unsigned long x,unsigned long y);
unsigned long getnumber(char *buffer);
int getstringparameter(char *buffer,char *ret_string,char separator,char ret_sno);
void strcpy(char *string1,char *string2);
long int random(void);
void seed(long int seed);
int gets(char *);

typedef unsigned char *va_list;
typedef int (*fnptr_t)(unsigned c, void **helper);
#define	STACKITEM	int
#define	VA_SIZE(TYPE)					\
	((sizeof(TYPE) + sizeof(STACKITEM) - 1)	\
		& ~(sizeof(STACKITEM) - 1))
#define	va_start(AP, LASTARG)	\
	(AP=((va_list)&(LASTARG) + VA_SIZE(LASTARG)))

#define va_end(AP)	/* nothing */

#define va_arg(AP, TYPE)	\
	(AP += VA_SIZE(TYPE), *((TYPE *)(AP - VA_SIZE(TYPE))))

#define		PR_LJ	0x01	/* left justify */
#define		PR_CA	0x02	/* use A-F instead of a-f for hex */
#define		PR_SG	0x04	/* signed numeric conversion (%d vs. %u) */
#define		PR_32	0x08	/* long (32-bit) numeric conversion */
#define		PR_16	0x10	/* short (16-bit) numeric conversion */
#define		PR_WS	0x20	/* PR_SG set and num was < 0 */
#define		PR_LZ	0x40	/* pad left with '0' instead of ' ' */
#define		PR_FP	0x80	/* pointers are far */
#define		PR_BUFLEN	16
#define	NULL	0
int printf(const char *fmt, ...);
int printdev(const char *fmt, ...);
void *malloc(unsigned long space);
#define __JMPBUF_LEN	9	/* Sized to match freebsd setjmp buffer */

typedef int jmp_buf[__JMPBUF_LEN];

int setjmp(jmp_buf env);
void longjmp(jmp_buf env, int val);


#define _U	0x01	/* upper */
#define _L	0x02	/* lower */
#define _D	0x04	/* digit */
#define _C	0x08	/* cntrl */
#define _P	0x10	/* punct */
#define _S	0x20	/* white space (space/lf/tab) */
#define _X	0x40	/* hex digit */
#define _SP	0x80	/* hard space (0x20) */
#define __ismask(x) (_ctype[(int)(unsigned char)(x)])
#define islower(c)	((__ismask(c)&(_L)) != 0)
#define isxdigit(c)	((__ismask(c)&(_D|_X)) != 0)


#define tolower(c) __tolower(c)
#define toupper(c) __toupper(c)

#define reg unsigned long

void print_num(unsigned long);
void print_mem(char *,reg);
char *strupr(char *);
size_t strspn(const char *,const char *);
int kbhit();
void * memset(void * s,char c,size_t count);
typedef reg state_var[7];
int log(const char *fmt,...);
void log_show();
void init_log();

struct BYTEREGS {
	unsigned char al,ah,bl,bh;
	unsigned char cl,ch,dl,dh;
};

struct WORDREGS {
	unsigned int ax,bx,cx,dx;
	unsigned int si,di,cflag,flags;
}; 

union REGS {
	struct WORDREGS x;
	struct BYTEREGS h;
};

int int86(int intno,union REGS *inregs,union REGS *outregs);
size_t linelen(const char *str);
int printstat(const char *fmt, ...);

#define assert(a,b) ({	\
	if(a)	{			\
	}	else	{   	\
		printf("\nAssertion failed [code]:%s",b);	\
		suspend_all();								\
	}                                           	\
})

//Singly Linked List macros:

#define create_head(structure,list_head) ({ \
	list_head=(structure *)get_mem(sizeof(structure)); \
	list_head->next=NULL; \
})

#define add_node(structure,to,node)	({ \
	to->next=(structure *)get_mem(sizeof(structure)); \
	node=to->next; \
	node->next=NULL; \
})

#define add_node_end(structure,list_head,node)	({                  \
	structure *tempnodeoflistnodeoflist;                                     \
	for(tempnodeoflistnodeoflist=list_head;(tempnodeoflistnodeoflist->next)!=NULL;tempnodeoflistnodeoflist=tempnodeoflistnodeoflist->next);	    \
	tempnodeoflistnodeoflist->next=(structure *)get_mem(sizeof(structure));         \
	tempnodeoflistnodeoflist=tempnodeoflistnodeoflist->next;                                            \
	tempnodeoflistnodeoflist->next=NULL;                                            \
	node=tempnodeoflistnodeoflist;													\
})

#define add_this_node_end(structure,list_head,node)	({ \
	structure *tempnodeoflistnodeoflist;                                     \
	for(tempnodeoflistnodeoflist=list_head;(tempnodeoflistnodeoflist->next)!=NULL;tempnodeoflistnodeoflist=tempnodeoflistnodeoflist->next);	    \
	tempnodeoflistnodeoflist->next=node;         \
})	


#define delete_node(structure,list_head,node)	({	\
	structure *tempnodeoflistnodeoflist; \
	for(tempnodeoflistnodeoflist=list_head;(tempnodeoflistnodeoflist->next)!=node && (tempnodeoflistnodeoflist->next)!=NULL;tempnodeoflistnodeoflist=tempnodeoflistnodeoflist->next); \
	tempnodeoflistnodeoflist->next=node->next; \
	free(node); \
})


#define get_node(structure,list_head,data,value,node) ({ \
	structure *tempnodeoflistnodeoflist; \
	for(tempnodeoflistnodeoflist=list_head;(tempnodeoflistnodeoflist->data)!=value && tempnodeoflistnodeoflist!=NULL;tempnodeoflistnodeoflist=tempnodeoflistnodeoflist->next); \
	node=tempnodeoflistnodeoflist; \
})

//Doubly Linked List macros:


#define dll_create_head(structure,list_head) ({	\
	list_head=(structure *)get_mem(sizeof(structure)); \
	list_head->prev=NULL; \
	list_head->next=NULL; \
})                                                


#define dll_add_node_end(structure,list_head,node)	({                  \
	structure *tempnodeoflistnodeoflist,*tempnodeoflistnodeoflist2;                                     \
	for(tempnodeoflistnodeoflist=list_head;(tempnodeoflistnodeoflist->next)!=NULL;tempnodeoflistnodeoflist=tempnodeoflistnodeoflist->next);	    \
	tempnodeoflistnodeoflist->next=(structure *)get_mem(sizeof(structure));         \
	tempnodeoflistnodeoflist2=tempnodeoflistnodeoflist;                                                 \
	tempnodeoflist=tempnodeoflist->next;                                            \
	tempnodeoflist->next=NULL;                                            \
	tempnodeoflist->prev=tempnodeoflist2;                                           \
	node=tempnodeoflist;													\
})

#define dll_add_node_start(structure,list_head,node) ({ \
	structure *tempnodeoflist; \
	node=(structure *)get_mem(sizeof(structure)); \
	tempnodeoflist=list_head->next; \
	list_head->next=node; \
	node->prev=list_head; \
	node->next=tempnodeoflist; \
})

#define dll_delete_node(structure,node)	({	\
	structure *tempnodeoflist,*tempnodeoflist2;             \
	tempnodeoflist=node->prev;                    \
	tempnodeoflist->next=node->next;              \
	tempnodeoflist2=node->next;                   \
	tempnodeoflist2->prev=tempnodeoflist;                   \
	free(node);                         \
})

#define dll_delete_node_at(structure,list_head,num) ({ \
	int location=num;                             \
	structure *node,*tempnodeoflist,*tempnodeoflist2;					\
	node=list_head;									\
	while(location>0 && (node->next)!=NULL)	{	\
		node=node->next;                         \
		location--;                                   \
	}	\
	tempnodeoflist=node->prev;                    \
	tempnodeoflist->next=node->next;              \
	tempnodeoflist2=node->next;                   \
	tempnodeoflist2->prev=tempnodeoflist;                   \
	free(node);                         \
})

#define dll_point_node(structure,list_head,num)	({   \
	int location=num;                            \
	structure *tempnodeoflist;                             \
	tempnodeoflist=list_head;                              \
	while(location>0 && (tempnodeoflist->next)!=NULL)	{        \
		tempnodeoflist=tempnodeoflist->next;                         \
		location--;                                   \
	}                                            \
	tempnodeoflist;                                        \
})

#define dll_add_node_at(structure,list_head,num,node) ({ \
	int location=num;                              \
	structure *tempnodeoflist,*tempnodeoflistnext; \
    tempnodeoflist=list_head;                              \
	while(location>0 && (tempnodeoflist->next)!=NULL)	{        \
		tempnodeoflist=tempnodeoflist->next;                         \
		location--;                                   \
	}                                            \
	tempnodeoflistnext=tempnodeoflist->next; \
	node=(structure *)get_mem(sizeof(structure)); \
	tempnodeoflist->next=node; \
	node->prev=tempnodeoflist; \
	node->next=tempnodeoflistnext; \
})


//List display macros:

#define show_all_list(structure,list_head) ({ \
	int i=0; \
	structure *tempnodeoflist; \
	for(tempnodeoflist=list_head;tempnodeoflist!=NULL;tempnodeoflist=tempnodeoflist->next)	{ \
		printf("\nList node #%d:\t0x%x",i,tempnodeoflist); \
		i++;	\
	} \
})

    


#define debugval(n) printf("\nDEBUG: 0x%x=%d",n,n)

char *strncpy(char *dest, const char *src, size_t count);

#define INIT(a) printdev(a)
#define INITSCS printdev("\t[DONE]")


//Error handling functions:


int i_error(const char *fmt, ...);
int ERROR(const char *fmt, ...);
	
#define disable cli
#define enable sti

typedef int spin_lock;

#define SPINSTATE 0x67
#define SPINRELEASE 0

int acquire_spin_lock(spin_lock *);
int release_spin_lock(spin_lock *);

#define bit0(a)  (a&0x1)
#define bit1(a)  (a&0x2)
#define bit2(a)  (a&0x4)
#define bit3(a)  (a&0x8)
#define bit4(a)  (a&0x10)
#define bit5(a)  (a&0x20)
#define bit6(a)  (a&0x40)
#define bit7(a)  (a&0x80)
#define bit8(a)  (a&0x100)
#define bit9(a)  (a&0x200)
#define bit10(a) (a&0x400)
#define bit11(a) (a&0x800)
#define bit12(a) (a&0x1000)
#define bit13(a) (a&0x2000)
#define bit14(a) (a&0x4000)
#define bit15(a) (a&0x8000)
#define bit16(a) (a&0x10000)
#define bit17(a) (a&0x20000)
#define bit18(a) (a&0x40000)
#define bit19(a) (a&0x80000)
#define bit20(a) (a&0x100000)
#define bit21(a) (a&0x200000)
#define bit22(a) (a&0x400000)
#define bit23(a) (a&0x800000)
#define bit24(a) (a&0x1000000)
#define bit25(a) (a&0x2000000)
#define bit26(a) (a&0x4000000)
#define bit27(a) (a&0x8000000)
#define bit28(a) (a&0x10000000)
#define bit29(a) (a&0x20000000)
#define bit30(a) (a&0x40000000)
#define bit31(a) (a&0x80000000)

#define set_bit0(a)  (a|=0x1)
#define set_bit1(a)  (a|=0x2)
#define set_bit2(a)  (a|=0x4)
#define set_bit3(a)  (a|=0x8)
#define set_bit4(a)  (a|=0x10)
#define set_bit5(a)  (a|=0x20)
#define set_bit6(a)  (a|=0x40)
#define set_bit7(a)  (a|=0x80)
#define set_bit8(a)  (a|=0x100)
#define set_bit9(a)  (a|=0x200)
#define set_bit10(a) (a|=0x400)
#define set_bit11(a) (a|=0x800)
#define set_bit12(a) (a|=0x1000)
#define set_bit13(a) (a|=0x2000)
#define set_bit14(a) (a|=0x4000)
#define set_bit15(a) (a|=0x8000)
#define set_bit16(a) (a|=0x10000)
#define set_bit17(a) (a|=0x20000)
#define set_bit18(a) (a|=0x40000)
#define set_bit19(a) (a|=0x80000)
#define set_bit20(a) (a|=0x100000)
#define set_bit21(a) (a|=0x200000)
#define set_bit22(a) (a|=0x400000)
#define set_bit23(a) (a|=0x800000)
#define set_bit24(a) (a|=0x1000000)
#define set_bit25(a) (a|=0x2000000)
#define set_bit26(a) (a|=0x4000000)
#define set_bit27(a) (a|=0x8000000)
#define set_bit28(a) (a|=0x10000000)
#define set_bit29(a) (a|=0x20000000)
#define set_bit30(a) (a|=0x40000000)
#define set_bit31(a) (a|=0x80000000)
